package chatServer.controller;

import java.io.*;
import java.net.*;
import java.util.*;

import chat.model.*;
 /**
 *  A simple Chat Server program that accompanies the Chat Client program.  Its main function is to allow easy 
 *  communication to and from the Client group (one or more).
 *
 * @author Tung Nguyen, Trung V Hoang, Rob Bernard, Justin Semmel
 * @see java.util.Observable
 * @since September 2012 
 */	
public class ChatServerConnection implements ObserverChatListener, ObserverableChatServer, Runnable
{
/*  'ChatServerConnection.java'  created by: Team N3 for Swinburne Uni HET715s2/Dr. Recep Ulusoy, 2/10/2012 v0.0 (final)
*   ===================================================================================
*
*   A simple Chat Server program that accompanies the Chat Client program.  Its main function is to allow easy 
*  communication to and from the Client group (one or more).
*
*   It monitors packets on its Server PC TCP Port 6666, then echos any packets back to the Client group, along. 
*   with the (version 4) IP of the sending PC.  
*   
*
*       NOTE:   a simple diagnostic log of Server activity is available on the CLI Window display.
*   
*   	Java Code Writers:  		Tung Nguyen and Trung Hoang      
*	Embedded documentation:              Rob Bernard
*	JavaDoc development:		Justin Semmel
*
*
*  The full program requires the following to be present in a PC to operate:
*  
*        - An Ethernet Port, managed by the Windows O/S (or similar);
*        - a Java Machine (pref. JRE6 or better) with the usual libraries (to run it - see User Manual), and ....
*        - a User Manual in older 'WORD' format ('J715projectTASK1/TASK2manual.doc').
*
*
*  OPERATION:
*
*	1.  Constructor for Server Connections
*	2.  Run I/O Stream              
*	3.   Connection Closer 
*	4.  Process message output
*	5.   Observers message Update
*	6.   Update Response message notification
*	7.   Add an extra Observer
*	8.   Chat User List update
*	9.   Chat User List, remove User from list
*
*  CLASSES CALLED:  ChatListener, ChatSender, ChatUser, Socket, ArrayList, Thread
*  ==============    Class and Method summary.  (done by Justin in JavaDocs?)
*/
	private Socket socket = null;
	private ChatListener chatListener;
	private ChatSender chatSender;
	private ChatUser chatUser;
	private ArrayList <ObserverChatServer> observerChatServerList;
	private String message;
	
	public ChatServerConnection(Socket theSocket)
	{
		//get the socket that connects to the client
		socket = theSocket;
		chatUser = new ChatUser();
		observerChatServerList = new ArrayList <ObserverChatServer>();
	}
	
	/**
	*   Run I/O Stream 
	*                (Create input and output stream to the client)
	*                 Add the current chatServerConnection to the ChatListener observer so when the chatListener receives a message, 
	*                 it will then notify the ChatServerConnection.  By doing that, we then can send it back to the controller, which 
	*                 manages all the connection.  From there, the message will be sent to all clients.
	*/
	public void run()
	{
		//create input and output stream to the client
		try
		{
//			observerList= new ArrayList <ObserverChat>();
			chatListener = new ChatListener(socket.getInputStream());
			chatSender = new ChatSender(socket.getOutputStream());
			
			//add the current chatServerConnection to the observer of the ChatListener
			//so when the chatListener receives a message, it will then notify the ChatServerConnection
			//by doing that, we then can send it back to the controller which manages all the connection
			// and from there, the message will be send to all clients.
			chatListener.addObserverChatListener(this);
			
			//create listening thread to get incoming messages
			Thread listenThread = new Thread(chatListener);
			listenThread.start();
		}
		catch(Exception ex)
		{
			System.out.println("\nError when allocating memory for variables!\n");
			System.exit(1);
		}
	}


	/**
	*   Connection Closer
	*                (Logs closing and disconnects socket)
	*/
	public void closeConnection()
	{
		try
		{
			System.out.println("\nClosing connection...");
			socket.close();
		}
		catch(IOException ioEx)
		{
			System.out.println("Unable to disconnect!");
			System.exit(1);
		}
	}
		
	/**
	*   Process message output
	*/
	public void sendMessage(String message)
	{
		chatSender.sendMessage(message);
	}
	
	//Observer patterns
	/**
	*  Observers message Update
	*	(Adds observers to the listener so whenever a new message comes in, all the observers will be notified.)
	*	[when sending a message, the server triggers the sending, so doesn't need to notify anyone.]	
	*/
	public void notifyObserverChatServer_ReceivingMessage(String message){
		for(ObserverChatServer observer:observerChatServerList)
		{
			observer.updateReceiveMessage(message, chatUser);
		}
	}
	
	/**
	*  Update Response message notification
	*/
	public void updateResponse(String message)
	{
		notifyObserverChatServer_ReceivingMessage(message);
	}

	/**
	*   Add an extra Observer
	*/		
	public void addObserverChatServer(ObserverChatServer observer)
	{
		observerChatServerList.add(observer);
	}
	/**
	*   Chat User List update
	*/		
	public void notifyObserverChatServer_ClientConnects()
	{
		for (ObserverChatServer observer:observerChatServerList)
		{
			observer.updateChatUserList_add(chatUser);
		}
	}
	/**
	*   Chat User List, remove User from list
	*/	
	public void notifyObserverChatServer_ClientLeaves()
	{
		for (ObserverChatServer observer:observerChatServerList)
		{
			observer.updateChatUserList_remove(chatUser);
		}
	}
}